package org.dfl.core.utils;

import java.io.InputStream;
import java.net.URL;

import javax.xml.parsers.SAXParserFactory;

import org.dfl.messages.Messages;
import org.iso_relax.jaxp.ValidatingSAXParserFactory;
import org.iso_relax.verifier.Schema;
import org.iso_relax.verifier.VerifierFactory;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;


/**
 * class to check integrity xml files with rng schemas
 * @author Piotr Wlodarczyk
 *
 */
public class RNGUtils {	
	/**
	 * check if the xml file is OK with rng schema
	 * @param filename	- xml file name
	 * @param rngSchemaFilename - nrg schema filename
	 * @throws Exception - error 
	 */
	public static void checkRNGFileIntegrity(String filename, URL rngSchemaFilename) throws Exception{
		//		 create a RELAX NG validator
		VerifierFactory factory = VerifierFactory
				.newInstance("http://relaxng.org/ns/structure/1.0"); //$NON-NLS-1$

		// compile a schema
		InputStream uis  = rngSchemaFilename.openStream();
		Schema schema = factory.compileSchema(uis);
		
		// wrap it into a JAXP
		SAXParserFactory parserFactory = new ValidatingSAXParserFactory(schema);

		// create a new XMLReader from it
		parserFactory.setNamespaceAware(true);
		XMLReader reader = parserFactory.newSAXParser().getXMLReader();

		// set an error handler
		// this error handler will throw an exception if there is an
		// well-formedness
		// error or a validation error.
		MyErrorHandler errors = new MyErrorHandler();
		reader.setErrorHandler(errors);

		// set the content handler
		reader.setContentHandler(new MyContentHandler());

		// parse the document
		reader.parse(filename);
		// if the execution reaches here, the document was valid and
		// there was nothing wrong.
	
		if(errors.e !=null){
			throw errors.e;
		}
	}
}


class MyContentHandler implements ContentHandler {
	public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
	}

	public void endDocument() throws SAXException {
	}

	public void endElement(String arg0, String arg1, String arg2)
			throws SAXException {
	}

	public void endPrefixMapping(String arg0) throws SAXException {
	}

	public void ignorableWhitespace(char[] arg0, int arg1, int arg2)
			throws SAXException {
	}

	public void processingInstruction(String arg0, String arg1)
			throws SAXException {
	}

	public void setDocumentLocator(Locator arg0) {
	}

	public void skippedEntity(String arg0) throws SAXException {
	}

	public void startDocument() throws SAXException {
	}

	public void startElement(String arg0, String arg1, String arg2,
			Attributes arg3) throws SAXException {
	}

	public void startPrefixMapping(String arg0, String arg1)
			throws SAXException {
	}
}

class MyErrorHandler implements ErrorHandler {
	Exception e;
	
	public void warning(SAXParseException exception) {
	    if(e==null)
	    	e = new Exception(Messages.FlowLaucher_warning1 + exception.getMessage()+Messages.FlowLaucher_warning2 + exception.getLineNumber()+ Messages.FlowLaucher_warning3 + exception.getColumnNumber());
	  }
	  public void error(SAXParseException exception) {
		  if(e==null)
		    	e = new Exception(Messages.FlowLaucher_error1 + exception.getMessage()+Messages.FlowLaucher_error2 + exception.getLineNumber()+ Messages.FlowLaucher_error3 + exception.getColumnNumber());
	  } 
	  public void fatalError(SAXParseException exception) {
		  if(e==null)
		    	e = new Exception(Messages.FlowLaucher_fatal1 + exception.getMessage()+Messages.FlowLaucher_fatal2 + exception.getLineNumber()+ Messages.FlowLaucher_fatal3 + exception.getColumnNumber());
	  }
	  
	  
}

